package com.jiunuan.live.core.server.service.impl;

import com.alibaba.fastjson2.JSON;
import com.jiunuan.live.common.interfaces.topic.ImCoreServerProviderTopicNames;
import com.jiunuan.live.core.server.service.IMsgAckCheckService;
import com.jiunuan.live.framework.redis.starter.key.IMCoreServerProviderCacheKeyBuilder;
import com.jiunuan.live.im.dto.ImMsgBody;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.MQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @Author: JiuNuan
 * @CreateTime: 2024-08-17 14:27
 * @Description:
 */
@Service
@Slf4j
public class MsgAckCheckServiceImpl implements IMsgAckCheckService {
    @Resource
    private RedisTemplate<String,Object> redisTemplate;
    @Resource
    private IMCoreServerProviderCacheKeyBuilder cacheKeyBuilder;
    @Resource
    private MQProducer mqProducer;
    /**
     * 主要客户端发送的ack消息包到服务端后，调用进行ack记录的移除
     *
     * @param imMsgBody
     */
    @Override
    public void doMsgAck(ImMsgBody imMsgBody) {
        String imAckMapKey = cacheKeyBuilder.buildIMAckMapKey(imMsgBody.getUserId(),imMsgBody.getAppId());
        redisTemplate.opsForHash().delete(imAckMapKey,imMsgBody.getMsgId());
        redisTemplate.expire(imAckMapKey,30, TimeUnit.MINUTES);

    }

    /**
     * 记录消息的ack和times
     *
     * @param imMsgBody
     * @param times
     */
    @Override
    public void recordMsgAck(ImMsgBody imMsgBody, int times) {
        String imAckMapKey = cacheKeyBuilder.buildIMAckMapKey(imMsgBody.getUserId(),imMsgBody.getAppId());
        redisTemplate.opsForHash().put(imAckMapKey, imMsgBody.getMsgId(),times);
        redisTemplate.expire(imAckMapKey,30, TimeUnit.MINUTES);
    }

    /**
     * 发送延迟消息，用于进行消息重试功能
     *
     * @param imMsgBody
     */
    @Override
    public void sendDelayMsg(ImMsgBody imMsgBody) {
        String json = JSON.toJSONString(imMsgBody);
        Message message = new Message();
        message.setBody(json.getBytes());
        message.setTopic(ImCoreServerProviderTopicNames.JIUNUAN_LIVE_IM_ACK_MSG_TOPIC);
        /*
           延迟时间
           等级1 -> 1s
           等级2 -> 5s
           */
        message.setDelayTimeLevel(2);
        try{
            SendResult sendResult = mqProducer.send(message);
            log.info("[MsgAckCheckService] message:{},sendResult:{}",message,sendResult);
        }catch (Exception e){
            log.error("[MsgAckCheckService] 发送延迟消息失败",e);
        }
    }

    /**
     * 获取ack消息的重试次数
     *
     * @param msgId
     * @param userId
     * @param appId
     * @return
     */
    @Override
    public int getMsgAckTimes(String msgId, Long userId, Integer appId) {
        Object value = redisTemplate.opsForHash().get(cacheKeyBuilder.buildIMAckMapKey(userId,appId),msgId);
        if(value == null){
            return -1;
        }
        return (int) value;
    }
}
